<template>
  <div class="questionnaire-form">
    <div v-if="questions && questions.length > 0" class="questions-list">
      <!-- 进度指示器 -->
      <div class="progress-indicator">
        <div class="progress-stats">
          <span class="progress-status">{{ progressText }}</span>
          <span v-if="showQuestionStats" class="question-stats">
            已回答: {{ answeredQuestionsCount }} 题
          </span>
        </div>
        <el-progress 
          :percentage="progressPercentage" 
          :stroke-width="15"
          :color="progressBarColors"
        />
      </div>

      <!-- 只显示当前问题 -->
      <transition name="fade">
        <div v-if="currentQuestion" class="question-item">
          <div class="question-header">
            <span class="question-index">{{ currentQuestionIndex + 1 }}</span>
            <span class="question-text">{{ currentQuestion.questionText || '未命名问题' }}</span>
            <span v-if="currentQuestion.isRequired" class="required-mark">*</span>
          </div>

          <!-- 单选题 -->
          <div v-if="currentQuestion.questionType === 'single'" class="question-options">
            <el-radio-group v-model="formAnswers[currentQuestionIndex]" @change="handleAnswerChange(currentQuestionIndex, $event)">
              <div v-for="(option, optionIndex) in getOptions(currentQuestion)" :key="option.value" class="option-item">
                <el-radio :label="option.value" :disabled="readOnly">
                  {{ option.label }}
                </el-radio>
              </div>
            </el-radio-group>
          </div>

          <!-- 多选题 -->
          <div v-else-if="currentQuestion.questionType === 'multiple'" class="question-options">
            <el-checkbox-group v-model="formAnswers[currentQuestionIndex]" @change="handleAnswerChange(currentQuestionIndex, $event)">
              <div v-for="(option, optionIndex) in getOptions(currentQuestion)" :key="option.value" class="option-item">
                <el-checkbox :label="option.value" :disabled="readOnly">
                  {{ option.label }}
                </el-checkbox>
              </div>
            </el-checkbox-group>
          </div>

          <!-- 文本题 -->
          <div v-else-if="currentQuestion.questionType === 'text'" class="question-options">
            <el-input
              v-model="formAnswers[currentQuestionIndex]"
              type="textarea"
              :rows="3"
              placeholder="请输入您的回答"
              :disabled="readOnly"
              @blur="handleAnswerChange(currentQuestionIndex, formAnswers[currentQuestionIndex])"
              @keyup.enter="
                if (formAnswers[currentQuestionIndex] && formAnswers[currentQuestionIndex].trim()) {
                  handleAnswerChange(currentQuestionIndex, formAnswers[currentQuestionIndex]);
                  showNextQuestion();
                }
              "
            />
            <div class="input-helper">您也可以按Enter键提交回答</div>
          </div>
          
          <!-- 未知题型 -->
          <div v-else class="question-options">
            <el-alert
              title="未知的题目类型"
              type="error"
              :closable="false"
            />
          </div>

          <!-- 导航按钮区域 -->
          <div class="question-navigation">
            <div class="question-hint">
              <i class="el-icon-info-filled hint-icon"></i>
              {{ 
                currentQuestion.questionType === 'text' 
                  ? '请输入您的回答' 
                  : (currentQuestion.questionType === 'multiple' 
                    ? '请选择一个或多个选项' 
                    : '请选择一个选项')
              }}
            </div>
            <div class="navigation-buttons">
              <!-- 多选题和文本题的下一题按钮 -->
              <el-button 
                v-if="currentQuestion.questionType === 'multiple' || currentQuestion.questionType === 'text'"
                type="primary" 
                size="small"
                :disabled="currentQuestion.isRequired && 
                  (currentQuestion.questionType === 'multiple' 
                    ? (!formAnswers[currentQuestionIndex] || formAnswers[currentQuestionIndex].length === 0)
                    : (!formAnswers[currentQuestionIndex] || !formAnswers[currentQuestionIndex].trim()))"
                @click="showNextQuestion"
                class="next-question-btn"
              >
                下一题 <i class="el-icon-arrow-right"></i>
              </el-button>
              
              <!-- 提前完成问卷按钮 -->
              <el-button 
                v-if="canSubmitEarly && answeredQuestionsCount >= minRequiredQuestions" 
                type="primary" 
                size="small" 
                class="submit-early-btn"
                @click="handleEarlySubmit"
              >
                提前完成问卷 <i class="el-icon-check"></i>
              </el-button>
            </div>
          </div>
        </div>
      </transition>

      <!-- 完成页面 -->
      <div v-if="isCompleted" class="completion-page">
        <el-result
          icon="success"
          title="问卷已完成"
          sub-title="感谢您的参与！"
        >
          <template #extra>
            <div class="completion-stats">
              <div class="stat-item">
                <span class="stat-label">已回答问题:</span>
                <span class="stat-value">{{ answeredQuestionsCount }}</span>
              </div>
              <div v-if="props.maxQuestions > 0" class="stat-item">
                <span class="stat-label">问卷设定最大题数:</span>
                <span class="stat-value">{{ Math.min(props.maxQuestions, props.questions.length) }}</span>
              </div>
              <div class="stat-item">
                <span class="stat-label">问卷总题库题数:</span>
                <span class="stat-value">{{ props.questions.length }}</span>
              </div>
            </div>
          </template>
        </el-result>
      </div>
    </div>

    <div v-else class="empty-questions">
      <el-empty description="暂无问卷题目" />
    </div>
  </div>
</template>

<script setup>
import { ref, watch, computed, defineProps, defineEmits, onBeforeUnmount } from 'vue'
import { ArrowRight, Check, InfoFilled } from '@element-plus/icons-vue'

const props = defineProps({
  questions: {
    type: Array,
    default: () => []
  },
  modelValue: {
    type: Array,
    default: () => []
  },
  readOnly: {
    type: Boolean,
    default: false
  },
  maxQuestions: {
    type: Number,
    default: 0 // 0 表示不限制问题数量
  },
  minRequiredQuestions: {
    type: Number,
    default: 5 // 提前提交所需的最少题目数
  },
  canSubmitEarly: {
    type: Boolean,
    default: true
  },
  showQuestionStats: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['update:modelValue', 'answer-change', 'submit'])

// 表单答案
const formAnswers = ref([])

// 跟踪当前问题索引
const currentQuestionIndex = ref(0)

// 已回答的问题索引集合
const answeredQuestions = ref(new Set())

// 是否已完成问卷
const isCompleted = ref(false)

// 缓存每个问题的选项
const optionsCache = new Map()

// 用于随机选题的问题池
const questionPool = ref([])

// 计算当前问题
const currentQuestion = computed(() => {
  if (isCompleted.value) return null
  return props.questions[currentQuestionIndex.value] || null
})

// 计算是否为第一个问题
const isFirstQuestion = computed(() => currentQuestionIndex.value === 0)

// 计算是否为最后一个问题
const isLastQuestion = computed(() => {
  return currentQuestionIndex.value === props.questions.length - 1
})

// 计算已回答的问题数
const answeredQuestionsCount = computed(() => answeredQuestions.value.size)

// 计算进度百分比
const progressPercentage = computed(() => {
  const effectiveMax = props.maxQuestions > 0 
    ? Math.min(props.maxQuestions, props.questions.length) 
    : props.questions.length
    
  return Math.min(100, Math.round((answeredQuestionsCount.value / effectiveMax) * 100))
})

// 计算进度文本
const progressText = computed(() => {
  if (progressPercentage.value <= 25) return '刚刚开始...'
  if (progressPercentage.value <= 50) return '继续加油...'
  if (progressPercentage.value <= 75) return '已完成大半...'
  if (progressPercentage.value < 100) return '即将完成...'
  return '已完成!'
})

// 计算当前问题是否可以继续
const canProceed = computed(() => {
  // 如果当前题目已回答，允许继续
  if (answeredQuestions.value.has(currentQuestionIndex.value)) {
    return true
  }
  
  // 如果是必答题但未回答，不允许继续
  if (currentQuestion.value?.isRequired) {
    const answer = formAnswers.value[currentQuestionIndex.value]
    
    if (answer === null || answer === undefined) return false
    
    if (currentQuestion.value.questionType === 'multiple' && Array.isArray(answer)) {
      return answer.length > 0
    }
    
    return answer !== null && answer !== undefined && answer !== ''
  }
  
  // 非必答题可以跳过
  return true
})

// 判断选项是否为对象格式
const isOptionObject = (option) => {
  return typeof option === 'object' && option !== null && 'label' in option && 'value' in option
}

// 获取选项数组，确保安全访问
const getOptions = (question) => {
  if (!question || !question.id) return []
  
  // 使用问题ID作为唯一键
  const questionKey = `question_${question.id}`
  
  // 如果缓存中已有该问题的处理过的选项，直接返回
  if (optionsCache.has(questionKey)) {
    return optionsCache.get(questionKey)
  }
  
  let result = []
  
  if (!question.options) {
    result = []
  } 
  // 如果options是字符串，尝试解析JSON
  else if (typeof question.options === 'string') {
    try {
      const parsed = JSON.parse(question.options)
      // 确保每个选项有唯一标识
      result = ensureOptionValues(parsed)
    } catch (e) {
      console.error('解析选项数据失败:', e)
      result = []
    }
  } else {
    // 确保每个选项有唯一标识
    result = ensureOptionValues(Array.isArray(question.options) ? question.options : [])
  }
  
  // 将处理结果缓存
  optionsCache.set(questionKey, result)
  return result
}

// 确保每个选项都有唯一的值
const ensureOptionValues = (options) => {
  // 先检查是否有重复的value值
  const valueMap = new Map()
  
  return options.map((option, index) => {
    // 默认值
    let uniqueValue = `option_${index}` 
    let label = `选项${index+1}`
    let originalValue = null

    // 如果已经是对象
    if (isOptionObject(option)) {
      label = option.label || label
      originalValue = option.value
      
      // 确保value值不为空
      if (originalValue === null || originalValue === undefined) {
        originalValue = label
      }
      
      // 检查value是否已经存在，如果存在则添加索引
      if (valueMap.has(originalValue)) {
        // 已存在相同value，使用索引确保唯一性
        uniqueValue = `${index}_${originalValue}`
      } else {
        // 不存在相同value，直接使用
        uniqueValue = `${index}_${originalValue}`
        valueMap.set(originalValue, true)
      }
      
      return {
        ...option,
        originalValue,
        value: uniqueValue,
        label
      }
    }
    
    // 如果是字符串
    if (typeof option === 'string') {
      label = option
      originalValue = option
      
      // 检查value是否已经存在
      if (valueMap.has(originalValue)) {
        uniqueValue = `${index}_${originalValue}`
      } else {
        uniqueValue = `${index}_${originalValue}`
        valueMap.set(originalValue, true)
      }
      
      return {
        label,
        originalValue,
        value: uniqueValue
      }
    }
    
    // 其他情况处理
    return {
      label,
      originalValue: null,
      value: uniqueValue
    }
  })
}

// 初始化答案数组
const initAnswers = (questions) => {
  console.log('初始化答案数组，题目数量:', questions.length)
  return questions.map(q => {
    // 确保多选题初始化为空数组
    if (q.questionType === 'multiple') {
      console.log('初始化多选题答案为空数组')
      return []
    }
    return null
  })
}

// 显示下一个问题（真随机跳转）
const showNextQuestion = () => {
  // 标记当前问题已回答
  answeredQuestions.value.add(currentQuestionIndex.value)
  
  // 检查是否已达到最大问题数
  const effectiveMax = props.maxQuestions > 0 
    ? Math.min(props.maxQuestions, props.questions.length) 
    : props.questions.length
    
  if (answeredQuestionsCount.value >= effectiveMax) {
    isCompleted.value = true
    handleSubmit() // 自动提交问卷
    return
  }
  
  // 从问题池中选择下一个问题
  if (questionPool.value.length > 0) {
    // 随机选择下一个问题的索引
    const randomPoolIndex = Math.floor(Math.random() * questionPool.value.length)
    const nextQuestionIndex = questionPool.value[randomPoolIndex]
    
    // 从池中移除已选择的问题
    questionPool.value.splice(randomPoolIndex, 1)
    
    // 设置为当前问题
    currentQuestionIndex.value = nextQuestionIndex
  } else {
    // 所有问题都已回答，标记为完成
    isCompleted.value = true
    handleSubmit() // 自动提交问卷
  }
}

// 显示上一个问题
const showPreviousQuestion = () => {
  // 如果当前是完成状态，返回到最后一个问题
  if (isCompleted.value) {
    isCompleted.value = false
    currentQuestionIndex.value = props.questions.length - 1
    return
  }
  
  // 简单地返回上一个索引
  if (currentQuestionIndex.value > 0) {
    currentQuestionIndex.value--
  }
}

// 提交问卷
const handleSubmit = () => {
  emit('submit', formAnswers.value)
}

// 提前提交问卷
const handleEarlySubmit = () => {
  if (answeredQuestionsCount.value >= props.minRequiredQuestions) {
    isCompleted.value = true
    handleSubmit()
  }
}

// 进度条颜色
const progressBarColors = [
  { color: '#95d475', percentage: 25 },
  { color: '#6abf40', percentage: 50 },
  { color: '#5e5ce6', percentage: 75 },
  { color: '#409eff', percentage: 100 }
]

// 防止用户意外关闭页面
const handleBeforeUnload = (e) => {
  if (!isCompleted.value && answeredQuestionsCount.value > 0) {
    e.preventDefault()
    e.returnValue = '您尚未完成问卷，确定要离开吗？'
    return '您尚未完成问卷，确定要离开吗？'
  }
}

// 注册和卸载页面关闭警告
onBeforeUnmount(() => {
  window.removeEventListener('beforeunload', handleBeforeUnload)
})

// 初始化表单答案
watch(() => props.questions, (newQuestions) => {
  console.log('问卷题目数据变化:', newQuestions?.length)
  if (newQuestions && newQuestions.length > 0) {
    // 注册页面关闭警告
    window.addEventListener('beforeunload', handleBeforeUnload)
    
    // 重置状态
    answeredQuestions.value = new Set()
    isCompleted.value = false
    
    // 清空选项缓存，确保重新生成选项
    optionsCache.clear()
    
    // 初始化问题池 - 所有问题的索引
    questionPool.value = Array.from({ length: newQuestions.length }, (_, i) => i)
    
    // 随机选择第一个问题
    const randomFirstIndex = Math.floor(Math.random() * questionPool.value.length)
    currentQuestionIndex.value = questionPool.value[randomFirstIndex]
    
    // 从池中移除第一个问题
    questionPool.value.splice(randomFirstIndex, 1)
    
    // 遍历题目预处理选项，确保缓存已建立
    newQuestions.forEach(question => {
      if (question && question.id) {
        getOptions(question)
      }
    })
    
    const initialAnswers = initAnswers(newQuestions)
    console.log('初始化的答案数组:', JSON.stringify(initialAnswers))
    formAnswers.value = initialAnswers
  } else {
    formAnswers.value = []
  }
}, { immediate: true, deep: true })

// 同步外部传入的值
watch(() => props.modelValue, (newValue) => {
  console.log('外部传入答案值:', JSON.stringify(newValue))
  if (newValue && newValue.length > 0) {
    // 将外部传入的原始值转换为内部唯一值
    const internalValues = newValue.map((answer, i) => {
      const question = props.questions[i]
      if (!question) return null // 没有对应问题，返回 null

      if (question.questionType === 'multiple') {
        // 确保多选题值是数组
        let currentAnswer = Array.isArray(answer) ? answer : (answer ? [answer] : [])
        
        // 转换数组中的每个值
        const options = getOptions(question)
        return currentAnswer.map(value => {
          // 查找对应的选项
          const matchingOptions = options.filter(opt => opt.originalValue === value)
          
          // 如果有多个匹配项，使用第一个
          if (matchingOptions.length > 0) {
            return matchingOptions[0].value 
          }
          
          // 没有找到匹配项，使用第一个选项值作为默认
          if (options.length > 0) {
            console.warn(`未找到原始值 ${value} 的选项，使用默认值`)
            return options[0].value
          }
          
          return null
        }).filter(Boolean) // 过滤掉null和undefined
        
      } else if (question.questionType === 'single') {
        if (!answer) return null
        
        const options = getOptions(question)
        // 查找匹配原始值的选项
        const matchingOptions = options.filter(opt => opt.originalValue === answer)
        
        // 如果有匹配项，返回第一个
        if (matchingOptions.length > 0) {
          return matchingOptions[0].value
        }
        
        // 如果没有找到匹配项，返回第一个选项值作为默认
        if (options.length > 0) {
          console.warn(`未找到原始值 ${answer} 的选项，使用默认值`)
          return options[0].value
        }
        
        return null
      } else {
        // 文本题等
        return answer
      }
    })
    
    console.log('转换后的内部答案值:', JSON.stringify(internalValues))
    formAnswers.value = internalValues
    
    // 检查已回答问题
    internalValues.forEach((answer, index) => {
      if (answer !== null && answer !== undefined) {
        if (Array.isArray(answer) && answer.length > 0) {
          answeredQuestions.value.add(index)
        } else if (!Array.isArray(answer) && answer !== '') {
          answeredQuestions.value.add(index)
        }
      }
    })
  } else {
    // 如果外部值为空，也需要初始化 formAnswers
    if (props.questions && props.questions.length > 0) {
      formAnswers.value = initAnswers(props.questions)
    }
  }
}, { immediate: true, deep: true })

// 处理答案变化
const handleAnswerChange = (index, newValue) => {
  const questionType = props.questions[index]?.questionType
  console.log(`答案变化 - 索引: ${index}, 类型: ${questionType}, 新值:`, newValue)

  // 更新内部状态
  if (questionType === 'multiple') {
    // 多选题：确保是数组
    formAnswers.value[index] = Array.isArray(newValue) ? [...newValue] : [] 
  } else {
    // 单选题和文本题
    formAnswers.value[index] = newValue
  }
  
  // 强制更新formAnswers以确保Vue检测到变化
  formAnswers.value = [...formAnswers.value]
  
  console.log('更新后的formAnswers:', JSON.stringify(formAnswers.value))
  
  // 标记问题已回答
  if (newValue !== null && newValue !== undefined) {
    if (Array.isArray(newValue) && newValue.length > 0) {
      answeredQuestions.value.add(index)
    } else if (!Array.isArray(newValue) && newValue !== '') {
      answeredQuestions.value.add(index)
    }
  }

  // --- 转换回原始值并触发事件 ---
  const originalAnswers = formAnswers.value.map((answer, i) => {
    if (answer === null || answer === undefined) return answer

    const question = props.questions[i]
    if (!question) return answer

    const options = getOptions(question)

    if (question.questionType === 'multiple') {
      if (!Array.isArray(answer)) {
        console.warn(`多选题答案索引 ${i} 不是数组:`, answer)
        return []
      }
      // 将内部唯一值数组转换回原始值数组
      return answer.map(val => {
        const matchedOption = options.find(opt => opt.value === val)
        return matchedOption ? matchedOption.originalValue : val
      }).filter(val => val !== undefined && val !== null)
    } else if (question.questionType === 'single') {
      // 将内部唯一值转换回原始值
      const matchedOption = options.find(opt => opt.value === answer)
      return matchedOption ? matchedOption.originalValue : answer
    } else {
      // 文本题等
      return answer
    }
  })

  console.log('转换后的原始答案值:', JSON.stringify(originalAnswers))
  emit('update:modelValue', originalAnswers)

  // 构建当前变化的答案值用于事件触发
  let currentEmitValue = null
  const currentAnswer = formAnswers.value[index]
  const currentQuestion = props.questions[index]
  
  if (!currentQuestion) return
  
  const currentOptions = getOptions(currentQuestion)

  if (currentQuestion.questionType === 'multiple' && Array.isArray(currentAnswer)) {
    currentEmitValue = currentAnswer.map(val => {
      const matchedOption = currentOptions.find(opt => opt.value === val)
      return matchedOption ? matchedOption.originalValue : val
    }).filter(val => val !== undefined && val !== null)
  } else if (currentQuestion.questionType === 'single') {
    const matchedOption = currentOptions.find(opt => opt.value === currentAnswer)
    currentEmitValue = matchedOption ? matchedOption.originalValue : currentAnswer
  } else {
    currentEmitValue = currentAnswer // 文本题等直接使用
  }

  // 触发answer-change事件
  emit('answer-change', {
    index,
    value: currentEmitValue,
    questionType: currentQuestion.questionType
  })
  
  // 如果使用了v-model，确保在下一个tick更新
  setTimeout(() => {
    // 这是一个触发Vue更新的技巧
    const temp = [...formAnswers.value]
    formAnswers.value = temp
    
    // 单选题自动前进
    if (questionType === 'single') {
      // 给用户一点时间查看选择结果，然后前进到下一题
      setTimeout(() => {
        showNextQuestion()
      }, 500)
    }
  }, 0)
}
</script>

<style scoped>
.questionnaire-form {
  padding: 10px 0;
  max-width: 800px;
  margin: 0 auto;
}

.questions-list {
  margin: 20px 0;
}

.progress-indicator {
  margin-bottom: 20px;
  padding: 0 10px;
}

.progress-stats {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 14px;
}

.progress-status {
  color: var(--primary-color, #409eff);
  font-weight: 500;
}

.question-stats {
  color: #909399;
}

.question-item {
  margin-bottom: 24px;
  padding: 20px;
  border-radius: 8px;
  background-color: #f9f9f9;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
}

.question-header {
  display: flex;
  align-items: flex-start;
  margin-bottom: 16px;
}

.question-index {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background-color: var(--primary-color);
  color: white;
  border-radius: 50%;
  font-size: 14px;
  margin-right: 10px;
  flex-shrink: 0;
}

.question-text {
  font-size: 16px;
  font-weight: 500;
  color: #333;
  flex: 1;
}

.required-mark {
  color: #f56c6c;
  margin-left: 4px;
}

.question-options {
  padding-left: 38px;
  margin-bottom: 24px;
  position: relative;
}

.option-item {
  margin-bottom: 10px;
}

.question-navigation {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 16px;
  border-top: 1px solid #eaeaea;
}

.question-hint {
  color: #909399;
  font-size: 14px;
  font-style: italic;
  display: flex;
  align-items: center;
}

.hint-icon {
  margin-right: 5px;
  font-size: 14px;
  color: #909399;
}

.navigation-buttons {
  display: flex;
  gap: 10px;
  margin-left: auto;
}

.next-question-btn {
  background-color: #5e5ce6;
  border-color: #5e5ce6;
  min-width: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.next-question-btn i {
  margin-left: 4px;
}

.next-question-btn:hover {
  background-color: #4a48d4;
  border-color: #4a48d4;
}

.submit-early-btn {
  display: flex;
  align-items: center;
  justify-content: center;
}

.submit-early-btn i {
  margin-left: 4px;
}

.empty-questions {
  text-align: center;
  padding: 30px 0;
}

.completion-page {
  text-align: center;
  padding: 40px 0;
  animation: fadeIn 0.5s ease;
}

.completion-stats {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 400px;
  margin: 0 auto;
  padding: 15px;
  background-color: #f9f9f9;
  border-radius: 8px;
}

.stat-item {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px dashed #eaeaea;
}

.stat-item:last-child {
  border-bottom: none;
}

.stat-label {
  color: #606266;
}

.stat-value {
  font-weight: 600;
  color: var(--primary-color, #409eff);
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: translateY(10px);
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.input-helper {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
  text-align: right;
  font-style: italic;
}
</style> 